#ifndef WINIO_H
#define WINIO_H
#include <Windows.h>

#ifndef WINIO_DLL
#define WINIO_API extern "C" _declspec(dllexport)
#else
#define WINIO_API 
#endif
// Define the various device type values.  Note that values used by Microsoft
// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
// by customers.

#define FILE_DEVICE_WINIO 0x00008010

// Macro definition for defining IOCTL and FSCTL function control codes.
// Note that function codes 0-2047 are reserved for Microsoft Corporation,
// and 2048-4095 are reserved for customers.

#define WINIO_IOCTL_INDEX 0x810

// Define our own private IOCTL

#define IOCTL_WINIO_MAPPHYSTOLIN     CTL_CODE(FILE_DEVICE_WINIO,  \
	WINIO_IOCTL_INDEX,      \
	METHOD_BUFFERED,        \
	FILE_ANY_ACCESS)

#define IOCTL_WINIO_UNMAPPHYSADDR    CTL_CODE(FILE_DEVICE_WINIO,  \
	WINIO_IOCTL_INDEX + 1,  \
	METHOD_BUFFERED,        \
	FILE_ANY_ACCESS)

#define IOCTL_WINIO_ENABLEDIRECTIO   CTL_CODE(FILE_DEVICE_WINIO,  \
	WINIO_IOCTL_INDEX + 2,   \
	METHOD_BUFFERED,         \
	FILE_ANY_ACCESS)

#define IOCTL_WINIO_DISABLEDIRECTIO  CTL_CODE(FILE_DEVICE_WINIO,  \
	WINIO_IOCTL_INDEX + 3,   \
	METHOD_BUFFERED,         \
	FILE_ANY_ACCESS)

#define IOCTL_WINIO_READPORT		 CTL_CODE(FILE_DEVICE_WINIO,  \
	WINIO_IOCTL_INDEX + 4,   \
	METHOD_BUFFERED,         \
	FILE_ANY_ACCESS)

#define IOCTL_WINIO_WRITEPORT		 CTL_CODE(FILE_DEVICE_WINIO,  \
	WINIO_IOCTL_INDEX + 5,   \
	METHOD_BUFFERED,         \
	FILE_ANY_ACCESS)

#pragma pack(push)
#pragma pack(1)

struct tagPhysStruct
{
	DWORD64 dwPhysMemSizeInBytes;
	DWORD64 pvPhysAddress;
	DWORD64 PhysicalMemoryHandle;
	DWORD64 pvPhysMemLin;
	DWORD64 pvPhysSection;
};

struct tagPortStruct
{
	USHORT wPortAddr;
	ULONG dwPortVal;
	UCHAR bSize;
};

#pragma pack(pop)

WINIO_API BOOL IsWinIoDriverOpen();
WINIO_API BOOL GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal);
WINIO_API BOOL SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal);
WINIO_API BOOL  GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);
WINIO_API BOOL  SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);
WINIO_API BYTE  IoRead8(WORD wPortAddr);
WINIO_API WORD  IoRead16(WORD wPortAddr);
WINIO_API DWORD IoRead32(WORD wPortAddr);
WINIO_API BOOL  IoWrite8(WORD wPortAddr, BYTE uPortVal);
WINIO_API BOOL  IoWrite16(WORD wPortAddr, WORD uPortVal);
WINIO_API BOOL  IoWrite32(WORD wPortAddr, DWORD uPortVal);
WINIO_API BYTE  MmioRead8(DWORD64 dwPhysAddr);
WINIO_API WORD  MmioRead16(DWORD64 dwPhysAddr);
WINIO_API DWORD MmioRead32(DWORD64 dwPhysAddr);
WINIO_API BOOL  MmioWrite8(DWORD64 dwPhysAddr, BYTE uPhysVal);
WINIO_API BOOL  MmioWrite16(DWORD64 dwPhysAddr, WORD uPhysVal);
WINIO_API BOOL  MmioWrite32(DWORD64 dwPhysAddr, DWORD uPhysVal);
WINIO_API int  InitializeWinIo();
WINIO_API void ShutdownWinIo();

extern HANDLE hDriver;
extern BOOL IsWinIoInitialized;
#endif
